from vtk import *
class Drawer:
    def __init__(self,lattice,glattice,config,selector):
        self.g = glattice.graph
        self.maxlev = lattice.GetNumberOfLevels()
        self.lattice = lattice
        self.vertex = glattice.vertex
        self.vertex_inv = {v:k for k,v in glattice.vertex.items()}
        self.view = self.setup_viewer(config)
        self.label_ind = 0
        self.max_vertex_size = 5
        self.toggle_edges = False
        self.toggle_fullscreen = False
        
    # Graph-View Binding
        layout = vtkGraphLayout()
        layout.SetInput(glattice.graph)
        layout.SetLayoutStrategy(vtkPassThroughLayoutStrategy())
        self.view.AddRepresentationFromInputConnection(layout.GetOutputPort())
        self.view.SetLayoutStrategyToPassThrough()
        self.config = config
        self.view2 = self.setup_viewer(config)
        
    # THEMES
        self.set_theme_view1()
        self.set_theme_view2()
        self.view2_callback_on = False
        self.config = config
    # SETTING TEXT BOXES IN THE WINDOWS
        self.txt = vtk.vtkTextActor()
        self.txt2 = vtk.vtkTextActor()
        self.setup_textbox1()
        self.setup_textbox2()
        self.view2.GetRenderer().AddActor(self.txt)  
        self.view.GetRenderer().AddActor(self.txt2)
    # SETTING WINDOW TITLES
        self.view.GetRenderWindow().SetWindowName("LatExp - Main lattice")
        self.view2.GetRenderWindow().SetWindowName("LatExp - Explorer")
        #self.view.GetRenderWindow().SetFullScreen(True)
    
        
        self.view.ResetCamera()
        self.view.Render()
    
    def draw(self):
        self.view.GetInteractor().Start()

    def set_theme_view1(self):
        # THEME APPLICATION (LAYOUT)
        self.theme1 = vtkViewTheme()
        self.theme1.SetLineWidth(self.config.getint('Layout', 'line_width'))
        self.theme1.SetPointSize(self.config.getint('Layout', 'point_size'))
        self.theme1.SetSelectedCellColor(1,1,1)
        self.theme1.SetSelectedCellOpacity(0.1)
        self.theme1.SetSelectedPointColor(1,1,1)
        self.theme1.SetBackgroundColor2(0,0,0)
        self.theme1.SetBackgroundColor(0.125,0.062,0.239)
        self.theme1.SetCellOpacity(0.01)

        self.theme1.SetCellColor(0.819,0.862,0.909)
        self.theme1.SetPointSize(self.max_vertex_size)
        lut = vtkLookupTable()
        lut.SetNumberOfTableValues(len(self.vertex))
        lut.SetAlphaRange(0.1,1.0)
        lut.SetHueRange(0, 0)
        lut.SetSaturationRange(0, 0)
        lut.SetValueRange(1.0, 1.0)
        lut.Build()

        self.theme1.SetPointLookupTable(lut)       
        self.view.ApplyViewTheme(self.theme1)
        self.view.SetEdgeVisibility(self.toggle_edges)

    def set_theme_view2(self):
        # THEME APPLICATION (LAYOUT)
        theme = vtkViewTheme()
        theme.SetLineWidth(self.config.getint('Layout', 'line_width'))
        theme.SetPointSize(self.config.getint('Layout', 'point_size'))
        theme.SetSelectedCellColor(1,1,1)
        theme.SetSelectedCellOpacity(0.03)
        theme.SetSelectedPointColor(1,1,1)
        theme.SetBackgroundColor2(0,0,0)
        theme.SetBackgroundColor(0.125,0.062,0.239)
        theme.SetCellOpacity(0.03)
        lut = vtkLookupTable()
        lut.SetNumberOfTableValues(len(self.vertex))
        lut.SetAlphaRange(0.1,1.0)
        lut.SetHueRange(0, 0)
        lut.SetSaturationRange(0, 0)
        lut.SetValueRange(1.0, 1.0)
        lut.Build()
        
        theme.SetPointLookupTable(lut)       
        
        self.view2.ApplyViewTheme(theme)

    

    def setup_viewer(self,config):
        view = vtkGraphLayoutView()
        view.SetVertexLabelArrayName(config.get('Nodes', 'label_array'))
        view.SetVertexLabelVisibility(False)
        view.SetVertexLabelFontSize(config.getint('Nodes', 'font_size'))
        
        #view.SetVertexColorArrayName(config.get('Nodes', 'color_array'))

        #self.g.GetVertexData().AddArray(vertexColors)
        view.SetVertexColorArrayName(config.get('Nodes', 'color_array'))
        view.SetColorVertices(True)
        
        view.SetScalingArrayName(config.get('Nodes', 'size_array'))
        # NEVER USE GLYPH 4
        vtkRenderedGraphRepresentation.SafeDownCast(view.GetRepresentation(0)).SetGlyphType(config.getint('Nodes', 'glyph'))
        view.ScaledGlyphsOn()
        
        view.GetRepresentation(0).SetVertexHoverArrayName("intent")
        view.DisplayHoverTextOn()
        
        view.GetInteractor().GetInteractorStyle().AddObserver("CharEvent",self.keyPress)
        view.GetInteractor().GetInteractorStyle().AddObserver("StartInteractionEvent",self.resize_text_view2)
        view.GetRenderWindow().SetSize(config.getint('Layout', 'window_size_x'),config.getint('Layout', 'window_size_y'))
        #view.GetRenderWindow().SetFullScreen(True)
        return view

# DESCRIBING THE PROPERTIES OF THE SUBLATTICE
    def setup_textbox1(self):
        #TEXT 
        self.txt.SetInput("Select a concept in the main lattice.")
        self.txt.GetTextProperty()
        self.txt.GetTextProperty().SetFontFamilyToArial()
        self.txt.GetTextProperty().SetFontSize(self.config.getint("Text","font"))
        self.txt.GetTextProperty().SetColor(1,1,1)
        self.txt.GetTextProperty().SetOpacity(0.85)

# CONTAINING THE NAME OF THE PROGRM
    def setup_textbox2(self):
        self.txt2.SetInput("Constellattice (LatExp) v1.0alpha")
        self.txt2.GetTextProperty().SetFontFamilyToArial()
        self.txt2.GetTextProperty().SetFontSize(self.config.getint('Text','font'))
        self.txt2.GetTextProperty().SetColor(1,1,1)
        self.txt2.GetTextProperty().SetOpacity(0.55)
        self.txt2.SetDisplayPosition(self.config.getint("Text","dposx"),self.config.getint("Text","dposy"))

    def updateText(self,x):
        '''
        concept = self.extent[self.vertex_inv[int(x)]]
        summary = 'Concept ID: {} \n'.format(x)
        summary += 'Level: {} \n'.format(concept['level'])
        summary += 'Extent: {} \n'.format(concept['objects'])
        summary += 'Intent: {} \n'.format(concept['attributes'])
        summary += 'Stability: {} \n'.format(concept['stability'])
        #summary += str(concept)
        '''
        self.txt.SetInput(x.Summary())
     
    def printFieldType(self,field_type):
           if field_type == 3:
               print "Vertices Selected:"
           elif field_type == 4:
               print "Edges Selected:"
           else:
               print "Unknown type:"

##################################################################
# FUNCTIONS REQUIRED FOR MAC COMPATIBILITY
# press p to toggle panning
# press z to toggle zooming
# press s to toggle select
##################################################################
    def resize_text_view2(self,obj,event):
        window_size = self.view2.GetRenderWindow().GetSize()
        self.txt.SetDisplayPosition(self.config.getint("Text","dposx"),window_size[1] - 50 - self.config.getint("Text","dposy"))

    def keyPress(self,obj,event):
        int = obj.GetInteractor()
        key = int.GetKeySym()
        if key == 'm':
            obj.RemoveObservers("LeftButtonPressEvent")
            obj.RemoveObservers("LeftButtonReleaseEvent")
            obj.AddObserver("LeftButtonPressEvent",self.startPan)
            obj.AddObserver("LeftButtonReleaseEvent",self.endPan)
        elif key == 'z':
            obj.RemoveObservers("LeftButtonPressEvent")
            obj.RemoveObservers("LeftButtonReleaseEvent")
            obj.AddObserver("LeftButtonPressEvent",self.startZoom)
            obj.AddObserver("LeftButtonReleaseEvent",self.endZoom)
        elif key == 's':
            obj.RemoveObservers("LeftButtonPressEvent")
            obj.RemoveObservers("LeftButtonReleaseEvent")
            obj.AddObserver("LeftButtonPressEvent",self.startSelect)
            obj.AddObserver("LeftButtonReleaseEvent",self.endSelect)
        elif key == 'q':
            exit()
        elif key == 'f':
            if self.toggle_fullscreen:
                self.toggle_fullscreen = False
            else:
                self.toggle_fullscreen = True
            self.view.GetRenderWindow().SetFullScreen(self.toggle_fullscreen)
        elif key == 'l':
            self.label_ind += 1
            self.label_ind = self.label_ind%4
            if self.label_ind == 0:
                self.view.SetVertexLabelVisibility(True)
                self.view2.SetVertexLabelVisibility(True)
                self.view.SetVertexLabelArrayName("extent")
                self.view2.SetVertexLabelArrayName("extent")
            elif self.label_ind == 1:
                self.view.SetVertexLabelArrayName("intent")
                self.view2.SetVertexLabelArrayName("intent")
            elif self.label_ind == 2:
                self.view.SetVertexLabelArrayName("extint")
                self.view2.SetVertexLabelArrayName("extint")
            elif self.label_ind == 3:
                self.view.SetVertexLabelVisibility(False)
                self.view2.SetVertexLabelVisibility(False)
        elif key == 'plus':
            self.max_vertex_size +=1
            self.theme1.SetPointSize(self.max_vertex_size)
            self.view.ApplyViewTheme(self.theme1)
        elif key == 'minus':
            self.max_vertex_size -=1
            if self.max_vertex_size < 1:
                self.max_vertex_size = 1
            self.theme1.SetPointSize(self.max_vertex_size)
            self.view.ApplyViewTheme(self.theme1)
        elif key == 'x':
            if self.toggle_edges:
                self.toggle_edges = False
            else:
                self.toggle_edges = True
            self.view.SetEdgeVisibility(self.toggle_edges)
        print key
        self.view.Render()
        self.view2.Render()
        obj.OnChar()

    @staticmethod
    def startPan(obj,event):
        #print 'panning'
        obj.OnMiddleButtonDown()
    @staticmethod
    def endPan(obj,event):
        obj.OnMiddleButtonUp()
    @staticmethod
    def startZoom(obj,event):
        #print 'zooming'
        obj.OnRightButtonDown()
    @staticmethod
    def endZoom(obj,event):
        obj.OnRightButtonUp()
    @staticmethod
    def startSelect(obj,event):
        #print 'selecting'
        obj.OnLeftButtonDown()
    @staticmethod
    def endSelect(obj,event):
        obj.OnLeftButtonUp()


